package org.goldfish.demo.apicall.analysis.code.upload;


import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.VBox;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.goldfish.demo.apicall.analysis.code.di.SpringFXMLLoader;
import org.goldfish.demo.apicall.analysis.code.select.ProjectSelectorController;
import org.goldfish.demo.apicall.analysis.code.upload.codeselect.CharsetDetector;
import org.goldfish.demo.apicall.analysis.code.upload.codeselect.FileDisplayHandler;
import org.goldfish.demo.apicall.analysis.code.upload.codeselect.GitIgnoreScanner;
import org.goldfish.demo.apicall.analysis.code.upload.messager.interfaces.LargeModelClient;
import org.goldfish.demo.apicall.analysis.code.upload.model.PdfImageAnalysis;
import org.goldfish.demo.apicall.analysis.code.upload.model.SourceFileAnalysis;
import org.goldfish.demo.apicall.analysis.code.upload.model.SourceFilePanelController;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
@RequiredArgsConstructor
@Slf4j
public class AnalysisController {

    private final ExecutorService executor = Executors.newFixedThreadPool(
            Runtime.getRuntime().availableProcessors()
    );


    private final GitIgnoreScanner scanner;
    private final CharsetDetector detector;
    private final ProjectSelectorController folderSelector; // 选择文件夹的控制器
    private final LargeModelClient largeModelClient;        // 大模型客户端


    @FXML
    private VBox fileContainer;

    private final FileDisplayHandler fileDisplayHandler = sfa ->
            Platform.runLater(() -> {
        try {
            FXMLLoader loader = new SpringFXMLLoader("source_file_panel.fxml");
            VBox panel = loader.load();

            SourceFilePanelController controller = loader.getController();
            controller.setSourceFileAnalysis(sfa);
            log.info("文件已添加: {} ", sfa.getFile().getAbsoluteFile());

            fileContainer.getChildren().add(panel);
        } catch (IOException e) {
            log.error("加载文件面板失败", e);
        }catch (Error e){
            log.error("加载文件面板失败", e);
            System.exit(0);
        }
    });

    @Bean
    public ExecutorService service() {
        return executor;
    }

    private List<File> sourceFiles;



    public void execute() throws IOException {
        execute(List.of(folderSelector.getSelectedPath()));
    }

    // 新增方法：支持多个路径分析
    public void execute(List<String> paths) throws IOException {
        // 清空之前的容器
        fileContainer.getChildren().clear();
        
        // 检查是否包含PDF文件
        boolean hasPdfFiles = false;
        for (String path : paths) {
            File folder = new File(path);
            if (containsPdfFiles(folder)) {
                hasPdfFiles = true;
                break;
            }
        }
        
        if (hasPdfFiles) {
            // 处理PDF文件
            processPdfFiles(paths);
        } else {
            // 处理源代码文件（原有逻辑）
            processSourceFiles(paths);
        }
    }
    
    private boolean containsPdfFiles(File folder) {
        if (folder.isDirectory()) {
            File[] files = folder.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isDirectory()) {
                        if (containsPdfFiles(file)) {
                            return true;
                        }
                    } else if (file.getName().toLowerCase().endsWith(".pdf")) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    
    private void processPdfFiles(List<String> paths) throws IOException {
        // 收集所有PDF文件
        List<File> pdfFiles = new ArrayList<>();
        for (String path : paths) {
            File folder = new File(path);
            log.info("扫描路径 {}", path);
            if (!folder.isDirectory()) {
                log.warn("路径不是有效目录: {}", path);
                continue;
            }

            // 查找所有PDF文件
            findPdfFiles(folder, pdfFiles);
        }

        // 处理所有PDF文件
        for (File pdfFile : pdfFiles) {
            executor.submit(() -> {
                try {
                    processPdfFile(pdfFile);
                } catch (Exception e) {
                    log.error("处理PDF文件失败: {}", pdfFile.getAbsoluteFile().getName(), e);
                }
            });
        }
    }
    
    private void findPdfFiles(File folder, List<File> pdfFiles) {
        File[] files = folder.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    findPdfFiles(file, pdfFiles);
                } else if (file.getName().toLowerCase().endsWith(".pdf")) {
                    pdfFiles.add(file);
                }
            }
        }
    }
    
    private void processPdfFile(File pdfFile) throws IOException {
        log.info("正在处理PDF文件 {}", pdfFile.getAbsoluteFile());
        
        try (PDDocument document = PDDocument.load(pdfFile)) {
            PDFRenderer pdfRenderer = new PDFRenderer(document);
            int pageCount = document.getNumberOfPages();
            
            log.info("PDF文件 {} 包含 {} 页", pdfFile.getName(), pageCount);
            
            // 逐页处理PDF
            for (int i = 0; i < pageCount; i++) {
                BufferedImage image = pdfRenderer.renderImageWithDPI(i, 100);
                
                PdfImageAnalysis pdfImageAnalysis = PdfImageAnalysis.builder()
                        .file(pdfFile)
                        .image(image)
                        .pageNumber(i + 1)
                        .build();
                
                // 显示图片
                displayPdfImage(pdfImageAnalysis);
                
                // 调用大模型分析图片
                analyzeImageWithModel(pdfImageAnalysis);
            }
        }
    }
    
    private void displayPdfImage(PdfImageAnalysis pdfImageAnalysis) {
        Platform.runLater(() -> {
            try {
                FXMLLoader loader = new SpringFXMLLoader("pdf_image_panel.fxml");
                VBox panel = loader.load();

                // 获取控制器并设置数据
                Object controller = loader.getController();
                if (controller instanceof org.goldfish.demo.apicall.analysis.code.upload.model.PdfImagePanelController) {
                    ((org.goldfish.demo.apicall.analysis.code.upload.model.PdfImagePanelController) controller)
                            .setPdfImageAnalysis(pdfImageAnalysis);
                }
                
                log.info("PDF页面已添加: {} 页面 {}", 
                         pdfImageAnalysis.getFile().getAbsoluteFile(), 
                         pdfImageAnalysis.getPageNumber());

                fileContainer.getChildren().add(panel);
            } catch (IOException e) {
                log.error("加载PDF图片面板失败", e);
            } catch (Exception e) {
                log.error("加载PDF图片面板失败", e);
            }
        });
    }
    
    private void analyzeImageWithModel(PdfImageAnalysis pdfImageAnalysis) {
        try {
            // 这里应该调用大模型API分析图片
            // 由于当前LargeModelClient是为文本设计的，我们需要修改或扩展它来处理图片
            // 暂时用模拟响应
            String mockResponse = "这是PDF文件 " + 
                                  pdfImageAnalysis.getFile().getName() + 
                                  " 的第 " + pdfImageAnalysis.getPageNumber() + " 页的分析结果";
            
            pdfImageAnalysis.appendToken(mockResponse);
            log.info("页面 {} 的大模型返回结果:\n{}", 
                     pdfImageAnalysis.getPageNumber(), 
                     pdfImageAnalysis.getResponse());
        } catch (Exception e) {
            log.error("分析PDF页面失败: {}", pdfImageAnalysis.getPageNumber(), e);
        }
    }
    
    private void processSourceFiles(List<String> paths) throws IOException {
        // 清空之前的源文件列表
        sourceFiles = new ArrayList<>();
        
        // 收集所有路径下的文件
        for (String path : paths) {
            File folder = new File(path);
            log.info("扫描路径 {}", path);
            if (!folder.isDirectory()) {
                log.warn("路径不是有效目录: {}", path);
                continue;
            }

            List<File> files = scanner.scanWithGitignore(folder);
            sourceFiles.addAll(files);
        }

        // 处理所有收集到的文件
        for (File file : sourceFiles) {
            executor.submit(() -> {
                try {
                    log.info("正在处理文件 {}", file.getAbsoluteFile());
                    String detectedEncoding = detector.detectFileEncoding(file);
                    Charset charset = Charset.forName(detectedEncoding);
                    String content = Files.readString(file.toPath(), charset);

                    SourceFileAnalysis sfa = SourceFileAnalysis.builder()
                            .file(file)
                            .content(content)
                            .build();
                    sfa.appendToken("待实现");

                    fileDisplayHandler.display(sfa);

                    log.info("文件 {} 的大模型返回结果:\n{}", file.getName(), sfa.getResponse());
                } catch (Exception e) {
                    log.error("处理文件失败: {}", file.getAbsoluteFile().getName(), e);
                }
            });
        }
    }
    
    // 保留原有方法以保持向后兼容
    public void execute(String path) throws IOException {
        execute(List.of(path));
    }
}